﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.IO;
using System.Xml;
using System.Drawing;

namespace Reborn_Server.App1AppHandler
{
    public class PetManager
    {
        private Character MyCharacter;
        private List<Pet_Controller> Pets = new List<Pet_Controller>();

        public PetManager(Character myCharacter) 
        {
            MyCharacter = myCharacter;
        }

        public void AddPet(Pet_Controller pet)
        {
            lock (Pets)
            {
                Pets.Add(pet);
            }
            UpdatePets();
        }

        public void UpdatePets()
        {
            try
            {
                MyCharacter.ClientSocket.socket.BeginSend(this.toXML());
            }
            catch { }
        }

        public void ChangePetMotion(long CreatureGUID, Pet_Controller.PetMotion motionType)
        {
            lock (Pets)
            {
                foreach (Pet_Controller pet in Pets)
                {
                    if (CreatureGUID == pet.MyCreature.CreatureID || CreatureGUID == -1)
                        pet.MotionType = motionType;
                }
            }
        }

        public void AttackCreature(long CreatureGUID, long AttackCreatureGUID)
        {
            lock (Pets)
            {
                foreach (Pet_Controller pet in Pets)
                {
                    if (CreatureGUID == pet.MyCreature.CreatureID || CreatureGUID == -1)
                        pet.CreatureIDToAttack = AttackCreatureGUID;
                }
            }
        }

        public void MoveTo(long CreatureGUID, int MapX, int MapY)
        {
            lock (Pets)
            {
                foreach (Pet_Controller pet in Pets)
                {
                    if (CreatureGUID == pet.MyCreature.CreatureID || CreatureGUID == -1)
                        pet.MoveTo = new Point(MapX, MapY);
                }
            }
        }

        //Copies and returns the pet list for thread safety
        public List<Pet_Controller> GetPets()
        {
            List<Pet_Controller> _Pets = new List<Pet_Controller>();
            lock (Pets)
            {
                foreach (Pet_Controller pet in Pets)
                {
                    _Pets.Add(pet);
                }
            }
            return _Pets;
        }

        public void CharacterDismissPet(long CreatureGUID)
        {
            //Returns a copy of the pet list for thread safety
            List<Pet_Controller> _Pets = GetPets();

            foreach (Pet_Controller pet in _Pets)
            {
                lock (pet.MyCreature.creatureLock)
                {
                    if (CreatureGUID == pet.MyCreature.CreatureID || CreatureGUID == -1)
                    {
                        pet.Dismiss();
                    }
                }
            }
        }

        public void DismissPet(long CreatureGUID)
        {
            //Returns a copy of the pet list for thread safety
            List<Pet_Controller> _Pets = GetPets();

            foreach (Pet_Controller pet in _Pets)
            {
                if (CreatureGUID == pet.MyCreature.CreatureID || CreatureGUID == -1)
                {
                    //Async this because it may lock a different map than the origional lock, causing a deadlock
                    Action petDismissMethod = (Action)pet.Dismiss;
                    petDismissMethod.BeginInvoke(null, null);
                    
                    //pet.Dismiss();
                }
            }
        }

        public int NumPets()
        {
            lock (Pets)
            {
                return Pets.Count;
            }
        }

        public void RemovePet(Pet_Controller pet)
        {
            lock (Pets)
            {
                foreach (Pet_Controller pt in Pets)
                {
                    if (pt == pet)
                    {
                        Pets.Remove(pt);
                        break;
                    }
                }
            }
            UpdatePets();
        }

        public string toXML()
        {
            string result = "";

            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmldoc = new XmlTextWriter(stringWriter);

            xmldoc.WriteStartElement("pets");

            lock (Pets)
            {
                foreach (Pet_Controller pet in Pets)
                {
                    xmldoc.WriteStartElement("pet");
                    xmldoc.WriteAttributeString("creatureid", pet.MyCreature.CreatureID.ToString());
                    xmldoc.WriteEndElement();
                }
            }

            xmldoc.WriteEndElement();
            xmldoc.Flush();

            xmldoc.Close();

            stringWriter.Flush();

            result = stringWriter.ToString();

            return result;
        }

    }
}
